package com.nulldev.util.internal;

import java.lang.reflect.Method;

import com.nulldev.util.event.EventManager;
import com.nulldev.util.event.EventTarget;
import com.nulldev.util.java.JVMUtil;
import com.nulldev.util.java.ReflectionUtils;
import com.nulldev.util.java.swing.extSwing.eCrashDialog;

public class JDKSupportManager {
    private static double currentJDKVer = 0;

    public static void init() {}
    
    static {
    	currentJDKVer = JVMUtil.getJavaVer_Double();
    	EventManager.register(new JDKSupportManager());
    }
    
    @EventTarget
    public static void call(final IncompatJDKEvent event) {
    	final eCrashDialog error = eCrashDialog.main(event.getThrowable());
    	error.setTitle("nullUtil: Crash Report");
    	error.setMessageTitle("nullUtil: Unsupported function called.");
    	if (event.getObject() instanceof UnsupportedFromJDK) {
    		error.append("Maximum Expected JVM: " + event.expectedJVM());
    	}else if (event.getObject() instanceof UnsupportedUntilJDK) {
    		error.append("Minimum Expected JVM: " + event.expectedJVM());
    	}
    	error.append("JVM Reported: " + JVMUtil.getJavaVer_Double());
    	error.append("Error Class: " + event.getCls() + " @ " + event.getMethod());
    	error.waitForOK();
    }
    
    
    public static void createCall() {
    	final String cls = Thread.currentThread().getStackTrace()[2].getClassName();
    	final String method = Thread.currentThread().getStackTrace()[2].getMethodName();
    	try {
    		final Method m = ReflectionUtils.getMethod(ReflectionUtils.fetchClass(cls), method);
    		if (m.getAnnotation(UnsupportedFromJDK.class) != null) {
    			final UnsupportedFromJDK us = m.getAnnotation(UnsupportedFromJDK.class);
        		if (JVMUtil.getJavaVer_Double() > us.maxSupportedJDK()) {
        			final UnsupportedJDK t = new UnsupportedJDK("nullUtil.SelfChecker: A function called '" + method + "' in '" + cls + "' is unsupported and was called.");
        			final IncompatJDKEvent e = new IncompatJDKEvent(t, us);
        			e.setExpectedJVM(us.maxSupportedJDK());
        			e.setEData(cls, method);
        			call(e);
        		}
    		}else if (m.getAnnotation(UnsupportedUntilJDK.class) != null) {
    			final UnsupportedUntilJDK us = m.getAnnotation(UnsupportedUntilJDK.class);
        		if (JVMUtil.getJavaVer_Double() < us.minSupportedJDK()) {
        			final UnsupportedJDK t = new UnsupportedJDK("nullUtil.SelfChecker: A function called '" + method + "' in '" + cls + "' is unsupported and was called.");
        			final IncompatJDKEvent e = new IncompatJDKEvent(t, us);
        			e.setExpectedJVM(us.minSupportedJDK());
        			e.setEData(cls, method);
        			call(e);
        		}
    		}
    		
    	}catch (Exception e) {}
    }
    
    public static class UnsupportedJDK extends RuntimeException {

		public UnsupportedJDK(final String string) {
			super(string);
		}	
    }
}
